﻿using Ls.Core;
using Ls.Data;
using Ls.Utils;
using Ls.Web.Framework.Permissions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Ls.Web.Admin.Areas.Sys.Models
{
    public class MenuService : BaseService, IPermissionService
    {
        public const string MENU_CACHE_PRE = "MENU_";
        public override string CacheKeyPre => MENU_CACHE_PRE;

        public MenuService() : base("Default", "sys_menus", "菜单表")
        {
        }
        /// <summary>
        /// 获取菜单按钮
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="permissionName"></param>
        /// <param name="isSup"></param>
        /// <returns></returns>
        public List<dynamic> GetButtonList(long userId, string permissionName, bool isSup)
        {
           
            List<dynamic> menuList;
            string sql = @" select menu_id,name,icon, js_method,permission
                from sys_menus where menu_type = 1 and menu_status = 0
                and parent_id in (select menu_id from sys_menus where permission=@permission)";
            if (isSup)
            {
                menuList = db.Sql(sql+ " order by sort, menu_id").Parameter("permission", permissionName, DataTypes.String).QueryMany<dynamic>(); ;
            }
            else
            { 
                menuList = db.Sql(sql+ @"   and menu_id in (select a.auth_id 
                    from sys_user_role r join sys_auth a on a.obj_type =0 and a.auth_type = 0   and r.role_id =a.obj_id 
                    where r.user_id =@user_id
                    union all 
                    select a.auth_id 
                    from  sys_auth a    
                    where  a.obj_type =1 and a.auth_type = 0  and a.obj_id  =@user_id
                )  order by sort, menu_id ").Parameter("user_id", userId, DataTypes.Int64)
                .Parameter("permission", permissionName, DataTypes.String).QueryMany<dynamic>();
            } 
            return menuList;
        }
        public dynamic GetButton(long userId, string permissionName, bool isSup) {
            dynamic result;
            string sql = @" select  menu_id,name,icon, js_method,permission
                from sys_menus where menu_type = 1
                and  permission=@permission ";
            if (isSup)
            {
                result = db.Sql(sql).Parameter("permission", permissionName, DataTypes.String).QuerySingle<dynamic>();
            }
            else
            {
                result = db.Sql(sql + @"   and menu_id in (select a.auth_id 
                    from sys_user_role r join sys_auth a on a.obj_type =0 and a.auth_type = 0   and r.role_id =a.obj_id 
                    where r.user_id =@user_id
                    union all 
                    select a.auth_id 
                    from  sys_auth a    
                    where  a.obj_type =1 and a.auth_type = 0  and a.obj_id  =@user_id
                )  ").Parameter("user_id", userId, DataTypes.Int64)
                .Parameter("permission", permissionName, DataTypes.String).QuerySingle<dynamic>();
            }
            return result;
        }
         
        /// <summary>
        /// 权限检查
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="permissionName"></param>
        /// <returns></returns>
        public bool CheckPermission(long userId, string permissionName)
        {
            if (permissionName.IsNullOrEmpty())
            {
                return true;
            }
            string cacheKey = CacheKeyPre + "PERMISSION_" + userId;
            var dataList = CacheHelper.Get<List<string>>(cacheKey); // 获取缓存
            if (dataList == null || dataList.Count == 0)
            {
                dataList = db.Sql(@" select permission
                from sys_menus where   menu_id in (select a.auth_id 
                    from sys_user_role r join sys_auth a on a.obj_type =0 and a.auth_type = 0   and r.role_id =a.obj_id 
                    where r.user_id =@user_id
                    union all 
                    select a.auth_id 
                    from  sys_auth a    
                    where  a.obj_type =1 and a.auth_type = 0  and a.obj_id  =@user_id
                )   ")
               .Parameter("user_id", userId, DataTypes.Int64)
               //.Parameter("permission", permissionName, DataTypes.String)
               .QueryMany<string>().Where(p => p.IsNotNullOrEmpty()).Select(p => p.ToUpper()).ToList();
                CacheHelper.Set<List<string>>(cacheKey, dataList);// 设置缓存
            }
            string excuteString = permissionName;
            List<string> parameters = permissionName.RegexRelace("([^a-zA-Z0-9.|&])", "").Split('|', '&').ToList();
            foreach (string parameter in parameters)
            {
                if (parameter.IsNullOrEmpty()) continue;
                excuteString = excuteString.Replace(parameter, dataList.Contains(parameter.ToUpper()) ? "true" : "false");
            }
            return CommonHelper.ToBool(JintHelper.Excute(excuteString));
        }

        /// <summary>
        /// 获取所有数据
        /// </summary>
        /// <returns></returns>
        public List<dynamic> GetAllMenus()
        {
            var menuList = GetList<dynamic>(new { }, "menu_id,name,icon,url,parent_id,sort", "sort");
            return menuList;
        }
        #region 用户权限函数

        /// <summary>
        /// 获取用户模块
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="menu_position">菜单位置 0 后台菜单 1 经销商菜单 2 店面菜单 </param>
        /// <returns></returns>
        public List<object> GetUserModules(long userId, int menu_position)
        {
            int is_sup = db.Sql("select is_sup from sys_users where user_id = @user_id ")
                .Parameter("user_id", userId)
                .QuerySingle<int>();
            List<dynamic> menuList;
            if (is_sup == 1)
            {
                menuList = GetList<dynamic>(new { menu_type = 0, menu_position = menu_position, menu_status = 0, parent_id = 0 }, "menu_id,name,icon,url,parent_id,sort", "sort");
            }
            else
            {
                // 只获取菜单
                menuList = GetListBySql<dynamic>(@" select menu_id,name,icon,url,parent_id,sort
                from sys_menus where menu_type = 0 and menu_position =@menu_position and menu_status = 0 and parent_id = 0 and menu_id in (select a.auth_id 
                    from sys_user_role r join sys_auth a on a.obj_type =0 and a.auth_type = 0   and r.role_id =a.obj_id 
                    where r.user_id =@user_id
                    union all 
                    select a.auth_id 
                    from  sys_auth a    
                    where  a.obj_type =1 and a.auth_type = 0  and a.obj_id  =@user_id
                ) order by sort, menu_id ", new { user_id = userId, menu_position = menu_position });
            }
            List<object> result = GetChilds(0, menuList);
            return result;
        }
        /// <summary>
        /// 获取用户模块菜单
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="menu_position">菜单位置 0 后台菜单 1 经销商菜单 2 店面菜单 </param>
        /// <param name="moduleId">模块Id</param>
        /// <returns></returns>
        public List<object> GetUserModuleMenus(long userId, int menu_position, long moduleId)
        {
            int is_sup = db.Sql("select is_sup from sys_users where user_id = @user_id ")
                 .Parameter("user_id", userId)
                 .QuerySingle<int>();
            List<dynamic> menuList;
            if (is_sup == 1)
            {
                menuList = GetList<dynamic>(new { menu_type = 0, menu_position = menu_position, menu_status = 0 }, "menu_id,name,icon,url,parent_id,sort", "sort");
            }
            else
            {
                // 只获取菜单
                menuList = GetListBySql<dynamic>(@" select menu_id,name,icon,url,parent_id,sort
                from sys_menus where menu_type = 0 and menu_position =@menu_position and menu_status = 0 and menu_id in (select a.auth_id 
                    from sys_user_role r join sys_auth a on a.obj_type =0 and a.auth_type = 0   and r.role_id =a.obj_id 
                    where r.user_id =@user_id
                    union all 
                    select a.auth_id 
                    from  sys_auth a    
                    where  a.obj_type =1 and a.auth_type = 0  and a.obj_id  =@user_id
                ) order by sort, menu_id ", new { user_id = userId, menu_position = menu_position });
            }
            List<object> result = GetChilds(moduleId, menuList);
            return result;
        }
        /// <summary>
        /// 只获取菜单
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="menu_position">菜单位置 0 后台菜单 1 经销商菜单 2 店面菜单 </param>
        /// <returns></returns>
        public List<object> GetAllMenusForDS(long userId, int menu_position)
        {
            int is_sup = db.Sql("select is_sup from sys_users where user_id = @user_id ")
                .Parameter("user_id", userId)
                .QuerySingle<int>();
            List<dynamic> menuList;
            if (is_sup == 1)
            {
                menuList = GetList<dynamic>(new { menu_type = 0, menu_position = menu_position, menu_status = 0 }, "menu_id,name,icon,url,parent_id,sort", "sort");
            }
            else
            {
                // 只获取菜单
                menuList = GetListBySql<dynamic>(@" select menu_id,name,icon,url,parent_id,sort
                from sys_menus where menu_type = 0 and menu_position =@menu_position and menu_status = 0 and menu_id in (select a.auth_id 
                    from sys_user_role r join sys_auth a on a.obj_type =0 and a.auth_type = 0   and r.role_id =a.obj_id 
                    where r.user_id =@user_id
                    union all 
                    select a.auth_id 
                    from  sys_auth a    
                    where  a.obj_type =1 and a.auth_type = 0  and a.obj_id  =@user_id
                ) order by sort, menu_id ", new { user_id = userId, menu_position = menu_position });
            }
            List<object> result = GetChilds(0, menuList);
            return result;
        }

        private List<object> GetChilds(long pid, List<dynamic> ds)
        {
            List<object> result = new List<object>();
            var menus = ds.Where(d => d.parent_id == pid).OrderBy(d => d.sort).ToList();
            foreach (var menu in menus)
            {
                var children = GetChilds(CommonHelper.ToInt64(menu.menu_id), ds);
                if (children.Count > 0)
                {
                    result.Add(new { id = menu.menu_id, iconCls = menu.icon, text = menu.name, url = menu.url, children = children });
                }
                else
                {
                    result.Add(new { id = menu.menu_id, iconCls = menu.icon, text = menu.name, url = menu.url, });
                }
            }
            return result;
        }
        #endregion

    }
}
